package model.bullets;

import model.enemies.IEnemy;
import model.surface.Scale;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.PorterDuff.Mode;

/**
 * Abstract class implements all bullet methods for the game.
 * 
 * @author EvilTeam
 *
 */
public abstract class BulletSprite implements IBullet {
	private static final int SCALE_FACTOR_FOR_BULLET = 8;
	private static final int BULLET_SPEED = 30;

	private Scale scale = Scale.getInstanceOfScaleClass();
	private int damage;
	private Bitmap bulletImage;
	private Bitmap scaledImage;
	private float xAxisPoint, yAxisPoint;
	private IEnemy enemy;
	private boolean isHit;

	/**
	 * 
	 * Draw method for all bullets using Canvas.
	 * 
	 */
	@Override
	public void draw(Canvas canvas) {
		Rect sourceRectangular = new Rect(0, 0, this.scaledImage.getWidth(),
				this.scaledImage.getHeight());
		Rect destinationRectangular = new Rect((int) this.xAxisPoint,
				(int) this.yAxisPoint, (int) this.xAxisPoint
						+ scaledImage.getWidth() / SCALE_FACTOR_FOR_BULLET,
				(int) this.yAxisPoint + scaledImage.getHeight()
						/ SCALE_FACTOR_FOR_BULLET);
		canvas.drawBitmap(scaledImage, sourceRectangular,
				destinationRectangular, null);
	}

	/**
	 * 
	 * Updates the location of the bullet.
	 * 
	 */
	@Override
	public void updateMyLocation() {

		if (this.xAxisPoint > enemy.getX()) {
			this.xAxisPoint -= BULLET_SPEED;
		}
		if (this.xAxisPoint <= enemy.getX() - enemy.getWidth() / 2) {
			this.xAxisPoint += BULLET_SPEED;
		}
		if (this.yAxisPoint < enemy.getY() - enemy.getHeight()) {
			this.yAxisPoint += BULLET_SPEED;
		}
		if (this.yAxisPoint >= enemy.getY() - enemy.getHeight() / 2) {
			this.yAxisPoint -= BULLET_SPEED;
		}
		hit();
	}

	/**
	 *
	 *Checks if the bullet hit his target.
	 */
	@Override
	public void hit() {
		if ((this.getxAxisPoint() < enemy.getX() + enemy.getWidth() / 2 && this
				.getxAxisPoint() > enemy.getX() - enemy.getWidth() / 2)
				&& (this.getyAxisPoint() > (enemy.getY() - (enemy.getHeight())) && this
						.getyAxisPoint() < (enemy.getY() - enemy.getHeight() / 2))) {
			isHit = true;
			int health = enemy.getHealthPoints() - this.damage;
			enemy.setHealthPoints(health);
		}
	}

	@Override
	public void clearOldBitmap(Canvas canvas) {
		canvas.drawColor(0, Mode.CLEAR);
	}

	public void setDamage(int damage) {
		if (damage > 0)
			this.damage = damage;
	}

	public Bitmap getImage() {
		return bulletImage;
	}

	/**
	 * Scale down the image for different screens.
	 * 
	 * @param image
	 */
	public void setImage(Bitmap image) {
		if (image != null) {
			this.bulletImage = image;
			this.scaledImage = Bitmap.createScaledBitmap(this.bulletImage,
					(int) scale.getScaledHeightForImages(),
					(int) scale.getScaledWidthForImages(), true);
		}
	}

	public float getxAxisPoint() {
		return xAxisPoint;
	}

	public void setxAxisPoint(float xAxisPoint) {
		if (xAxisPoint > 0)
			this.xAxisPoint = xAxisPoint;
	}

	public float getyAxisPoint() {
		return yAxisPoint;
	}

	public void setyAxisPoint(float yAxisPoint) {
		if (yAxisPoint > 0)
			this.yAxisPoint = yAxisPoint;
	}

	public IEnemy getEnemy() {
		return enemy;
	}

	public void setEnemy(IEnemy enemy) {
		if (enemy != null)
			this.enemy = enemy;
	}

	public void setHit(boolean isHit) {
		this.isHit = isHit;
	}

	@Override
	public boolean isHit() {
		return isHit;
	}
}